#include "yaml-cpp/yaml.h"
#include <iostream>
#include "opengauss/libpq-fe.h"
#include <random>
#include <vector>
#include <string>
#include <ctime>
#include "db_conninfo.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"

// 生成随机整数
int randomInt(int min, int max)
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(min, max);
    return dis(gen);
}

// 生成随机时间
std::string randomTime()
{
    std::time_t currentTime = std::time(nullptr);
    std::time_t randomTime = currentTime - randomInt(0, 365 * 24 * 60 * 60); // 随机过去一年的时间
    std::tm *tm_info = std::localtime(&randomTime);

    char buffer[26];
    std::strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    return std::string(buffer);
}

// 生成随机字符串
std::string randomString(size_t length)
{
    static const std::string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, charset.size() - 1);

    std::string result;
    result.reserve(length);
    for (size_t i = 0; i < length; ++i)
    {
        result += charset[dis(gen)];
    }
    return result;
}

int main(int argc, char **argv)
{
    try
    {
        // 创建一个基本的文件日志记录器
        auto max_size = 1048576 * 5;
        auto max_files = 3;    
        auto file_logger = spdlog::rotating_logger_mt("basic_logger", "logs/basic-log.txt",max_size, max_files);
        // 设置日志级别为 debug
        file_logger->set_level(spdlog::level::debug);
        // 记录不同级别的日志
        file_logger->trace("This is a trace message");
        file_logger->debug("This is a debug message");
        file_logger->info("This is an info message");
        file_logger->warn("This is a warning message");
        file_logger->error("This is an error message");
        file_logger->critical("This is a critical message");
        // 刷新日志缓冲区
        file_logger->flush();
    }
    catch (const spdlog::spdlog_ex &ex)
    {
        std::cout << "Log initialization failed: " << ex.what() << std::endl;
    }
    const char *location;
    if (argc > 1)
        location = argv[1];
    else
        location = "../src/dh.yaml";

    YAML::Node config = YAML::LoadFile(location);
    std::cout << "Database Host: " << config["database"]["host"].as<std::string>() << std::endl;
    std::cout << "Database port: " << config["database"]["port"].as<std::int32_t>() << std::endl;
    std::cout << "Database username: " << config["database"]["username"].as<std::string>() << std::endl;
    std::cout << "Database password: " << config["database"]["password"].as<std::string>() << std::endl;
    std::cout << "skills c++:" << config["skills"]["c++"].as<int>() << std::endl;
    std::cout << "skills java:" << config["skills"]["java"].as<int>() << std::endl;
    std::cout << "skills android:" << config["skills"]["android"].as<int>() << std::endl;
    std::cout << "skills python:" << config["skills"]["python"].as<int>() << std::endl;
    for (YAML::const_iterator it = config["skills"].begin(); it != config["skills"].end(); ++it)
    {
        std::cout << it->first.as<std::string>() << ":" << it->second.as<int>() << std::endl;
    }
    std::cout << "Database Host: " << config["database_url"].as<std::string>() << std::endl;
    // 创建数据库连接
    PGconn *conn = createPGConnection(config["database_url"].as<std::string>());
    if (!conn)
    {
        return EXIT_FAILURE;
    }
    int status;
    status = CreateTable(conn);
    if (status != 0)
    {
        std::cerr << "连接数据库建立表出错: " << PQerrorMessage(conn) << std::endl;
        return EXIT_FAILURE;
    }
    // 目标表名
    std::string tableName = "my_table";
    int batchRecords = 10; // 生成 10 条测试数据
    std::string insertQuery = "INSERT INTO " + tableName + " (name, age) VALUES ";
    for (int i = 0; i < batchRecords; ++i)
    {
        if (i > 0)
        {
            insertQuery += ", ";
        }
        insertQuery += "('" + randomString(4) + "', " + std::to_string(randomInt(3, 8)) + ")";
    }
    std::cout << insertQuery.c_str() << std::endl;
    status = InsertTable(conn, insertQuery.c_str());
    if (status != 0)
    {
        std::cerr << "连接数据库导入数据出错: " << PQerrorMessage(conn) << std::endl;
        return EXIT_FAILURE;
    }
    return 0;
}